/*
 * Clase que gestiona funcionalidad de videojuego.
 * 
 */

package gestorvideoclub;

import gestorvideoclub.enumeraciones.*;
import gestorvideoclub.jdbc.FranquiciaJDBC;
import gestorvideoclub.jdbc.PeliculaJDBC;
import gestorvideoclub.jdbc.ProductoJDBC;
import gestorvideoclub.jdbc.ProveedorJDBC;
import gestorvideoclub.jdbc.TarifaJDBC;
import gestorvideoclub.jdbc.UbicacionJDBC;
import gestorvideoclub.jdbc.VideojuegoJDBC;
import gestorvideoclub.util.introduceDatos;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Rafa Berral
 */
public class Videojuego extends Producto{
    private GeneroVideojuegoEnum genero;
    private int NumJugadores;
    private String plataforma;
    private int anyo;


    /*
     *Constructores
     */
    public Videojuego(){}

    public Videojuego(int cod, String titulo, TipoProductoEnum tipo, ProductoEnum est,String desc, int edad,  double precio, Tarifa t, Ubicacion ub, Proveedor prov,Franquicia franq, String plat,int NumJug, GeneroVideojuegoEnum genero,int anno){
         super(cod, titulo,tipo, est, desc,edad, precio,t,ub,prov, franq);
         this.genero = genero;
         this.plataforma = plat;
         this.NumJugadores = NumJug;
         this.anyo = anno;
    }

    public int getNumJugadores() {
        return NumJugadores;
    }

    public int getAnyo() {
        return anyo;
    }

    public void setNumJugadores(int NumJugadores) {
        this.NumJugadores = NumJugadores;
    }

    public GeneroVideojuegoEnum getGenero() {
        return genero;
    }

    public void setAnyo(int anyo) {
        this.anyo = anyo;
    }

    public void setGenero(GeneroVideojuegoEnum genero) {
        this.genero = genero;
    }

    public String getPlataforma() {
        return plataforma;
    }

    public void setPlataforma(String plataforma) {
        this.plataforma = plataforma;
    }

    @Override
    public boolean equals (Object o){
        boolean dev=false;
        if(o instanceof Videojuego){
            Videojuego aux = (Videojuego) o;
            if((this.getCodigo()==aux.getCodigo()))
            {
                dev= true;
            }
            else
            {
                dev= false;
            }
        }
        return dev;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 61 * hash + (this.genero != null ? this.genero.hashCode() : 0);
        hash = 61 * hash + this.NumJugadores;
        hash = 61 * hash + (this.plataforma != null ? this.plataforma.hashCode() : 0);
        hash = 61 * hash + this.anyo;
        return hash;
    }
    
    @Override
    public String toString() {
        return super.toString()+ "\n||genero:" + genero + " || NumJugadores:" + NumJugadores + " || plataforma:" + plataforma+ "|| Año: "+anyo;
    }

    //@Override
    public static void recorreLista(List l){
        int cont=1;
        try{
            for(Object p : l){
                Videojuego aux = (Videojuego)p;
                //comprueba antes si la tarifa del videojuego ha caducado. 
                //si es asi, cambiamos la tarifa y la actualizamos por una tarifa por defecto
                if(TarifaJDBC.compruebaCaducidadTarifa(aux))
                {
                    aux.setTarifa(TarifaJDBC.DevuelveTarifaPorDefecto(aux.getTipo()));
                    VideojuegoJDBC.sobreescribeVideojuego(aux, aux.getCodigo());
                }
                System.out.print("\n---VIDEOJUEGO NUMERO "+cont+"---");
                System.out.println(aux);
                cont++;
            }
        }catch(NullPointerException e){
            System.out.println("Error al imprimir listado de videojuego");
        }
    }
    /*
     * metodo donde damos de baja un videojuego.
     * simplemente actualizamos el estado del producto a "baja"
     */
    @Override
    public void bajaProducto() {
        int numero, codigo=0;
        boolean salir = false;
        do{
            System.out.println("\nDesea dar de baja un videojuego? Seleccione una opcion:");
            System.out.println("1. Si");
            System.out.println("2. No");
            int op = introduceDatos.introduceEntero2();
            switch(op){
                case 1:
                    System.out.println("Introduce codigo de videojuego: ");
                    codigo = introduceDatos.introduceEntero2();
                    if(ProductoJDBC.compruebaCodigo(codigo)>0)
                    {
                        Videojuego video = VideojuegoJDBC.obtenerVideojuegoPorId(codigo);
                        video.setEstado(ProductoEnum.Baja);
                        VideojuegoJDBC.modificaEstado(video);
                        salir = true;
                        System.out.println("Producto Dado de baja.");
                        break;
                    }
                    else
                        System.out.println("Videojuego no encontrado");

                case 2:
                    salir = true;
                    break;
                default:
                    System.out.println("Opcion incorrecta");
            }
        }while(!salir);
        
    }

    /*
     * metodo utilizado para cualquier modificacion del Producto, en este caso el Videojuego
     */
    @Override
    public void modificacionProducto() {
        GeneroVideojuegoEnum [] arrayG = rellenaArrayGenero(); 
        String nombre=null,recoge="";
        Tarifa t = new Tarifa();
        boolean enc=false,listo=false, salir3=false;
        ProductoEnum [] arrayE = new ProductoEnum[ProductoEnum.values().length]; //Guarda Enumeracion de productos
       //Cargamos generos devideojuegos en array
        arrayG = rellenaArrayGenero();
        //Cargamos estados pelicula en array
        arrayE = rellenaArrayProductoEnum();
        int numero,eligeOpcion,codigo=0,aux,idUbi;
        Videojuego video;
        Ubicacion ubi = new Ubicacion();
        System.out.println("Introduzca Codigo del Videojuego: ");
        codigo = introduceDatos.introduceEntero2();
        video = VideojuegoJDBC.obtenerVideojuegoPorId(codigo);//BBDD devuelve videojuego filtrado por 'codigo'
        try{
            System.out.println(video.toString());//muestra el videojuego
        }catch(NullPointerException e){
            System.out.println("No Existe Videojuego");
            salir3 = true;
        } if(!salir3) {
            video.toString();
            do{
                do{
                System.out.println("Introduce dato que quieres modificar: ");
                System.out.println("1.- Titulo");
                System.out.println("2.- Plataforma");
                System.out.println("3.-Descripcion");
                System.out.println("4.- Numero de Jugadores");
                System.out.println("5.- Ubicacion");
                System.out.println("6.- Año");
                System.out.println("7.- Genero");
                System.out.println("8.- Edad Recomendada");
                System.out.println("9.- Estado del Producto");
                System.out.println("10.- Precio Compra");
                System.out.println("11.- Tarifa");
                System.out.println("12.- Proveedor");
                System.out.println("13.- SALIR");
                numero = introduceDatos.introduceEntero2();
                }while(numero>13 || numero<1);
                switch(numero){
                    case 1: System.out.println("Introduce Nuevo Titulo: ");
                            video.setTitulo(introduceDatos.introduceString2());break;
                    case 2: System.out.println("Introduce Nueva Plataforma: ");
                            video.setPlataforma(introduceDatos.introduceString2());break;
                    case 3: System.out.println("Introduce Nueva Descripcion: ");
                            video.setDescripcion(introduceDatos.introduceString2());break;
                    case 4: System.out.println("Introduce Nuevo Num. Jugadores: ");
                            video.setNumJugadores(introduceDatos.introduceEntero2());break;
                    case 5: System.out.println("Videojuego ubicado en "+video.getUbicacion().getPosicionamiento()+", cambiar (s/n):");
                            recoge = introduceDatos.introduceString2();
                             do{
                                if(recoge.compareToIgnoreCase("s")==0 || recoge.compareToIgnoreCase("n")==0)
                                     listo=true;
                                else
                                {
                                    System.out.println("Introduzca s/n por favor: ");
                                    recoge = introduceDatos.introduceString2();
                                }                      
                            }while(!listo);
                                //comprobamos si el producto está en cajero
                                if(recoge.compareToIgnoreCase("s")==0 && video.getUbicacion().getPosicionamiento().compareTo("Cajero")==0)
                                {
                                   //recogemos ubicacion antigua, la dejamos libre y actualizamos a ubicacion de tienda
                                   ubi = video.getUbicacion();
                                   ubi.setOcupado(false);
                                   UbicacionJDBC.modificaUbicacion(ubi);
                                   ubi.setId(1);
                                }
                                else if(recoge.compareToIgnoreCase("s")==0 && video.getUbicacion().getPosicionamiento().compareTo("Tienda")==0)
                                {
                                    //buscamos ubicacion nueva y la añadimos
                                    idUbi = UbicacionJDBC.BuscaIdUbicacionLibre();
                                    if(idUbi!=-1)
                                    {
                                        ubi = UbicacionJDBC.devuelveUbicacion(idUbi);
                                        ubi.setPosicionamiento("Cajero");
                                        UbicacionJDBC.insertaUbicacion(ubi);
                                    }
                                    else
                                    {
                                        System.out.println("ERROR! CAJERO LLENO, el producto se asignara a tienda");
                                        ubi.setPosicionamiento("Tienda");
                                        ubi.setId(1);
                                        ubi.setColumna(-1);
                                        ubi.setFila(-1);
                                        ubi.setOcupado(true);
                                    }
                                }
                                video.setUbicacion(ubi);
                                break;
                    case 6: System.out.println("Introduce Nuevo Año: ");
                            video.setAnyo(introduceDatos.introduceEntero2());break;

                    case 7: listadoGenero();
                            eligeOpcion = recogeOpcion(arrayG.length);
                            video.setGenero(arrayG[eligeOpcion]);
                            break;

                    case 8: System.out.println("Introduce Nueva Edad Recomendada: ");
                            video.setEdadRecomendada(introduceDatos.introduceEntero2());break;

                    case 9: recorreEstadoProducto();
                            eligeOpcion = recogeOpcion(arrayE.length);
                            video.setEstado(arrayE[eligeOpcion]);
                            break;

                    case 10: System.out.println("Introduce Nuevo Precio de Compra: ");
                            video.setPrecioCompraProducto(introduceDatos.introduceDouble2());break;


                    case 11: /* pasamos "TipoProducto" para que nos devuelva un listado de las tarifas
                             * asociadas al tipo de producto pasado y que esten activas en ese momento
                             */
                            List<Tarifa> listaT = tarifasFiltroTipoProductoFecha(TipoProductoEnum.Videojuego);
                            if(listaT.isEmpty())
                            {
                                System.out.println("No se encontraron tarifas, se aplicara una por defecto");
                                t=TarifaJDBC.DevuelveTarifaPorDefecto(TipoProductoEnum.Videojuego);
                                video.setTarifa(t);
                            }
                            else
                            {
                                recorreListaTarifa(listaT);
                                eligeOpcion = recogeOpcion(listaT.size());
                                video.setTarifa(listaT.get(eligeOpcion));//guarda tarifa elegida en pelicula
                            }
                            break;

                    case 12: List<Proveedor> listaProv = ProveedorJDBC.consultarProveedoresAlta();//la BBDD nos devuelve un listado de Proveedores
                            recorreListaProveedor(listaProv);
                            eligeOpcion =recogeOpcion(listaProv.size());
                            video.setProveedor(listaProv.get(eligeOpcion));//guarda proveedor elegido en videojuego
                            break;

                    default: System.out.println("Introduce valor entre 1-13");
                }
                System.out.println("Desear seguir modificando alguna propiedad del prodcucto actual(s/n): ");
                recoge = introduceDatos.introduceString2();
                do{
                    if(recoge.compareToIgnoreCase("s")==0 || recoge.compareToIgnoreCase("n")==0)
                         listo=true;
                    else
                    {
                        System.out.println("Introduzca s/n por favor: ");
                        recoge = introduceDatos.introduceString2();
                    }                      
                }while(!listo);

            }while(recoge.compareToIgnoreCase("s")==0);
            VideojuegoJDBC.sobreescribeVideojuego(video, codigo);
        }
    }

    /*
     * recorremos lista con videojuegos del mismo genero
    */
    @Override
    public void consultaGeneroProducto() {
        GeneroVideojuegoEnum [] arrayG = rellenaArrayGenero();
        listadoGenero();
        int posicion = recogeOpcion(arrayG.length);
        GeneroVideojuegoEnum genero = arrayG[posicion];
        List<Videojuego> lista = VideojuegoJDBC.consultaVideojuegosGenero(genero);
        if(lista.isEmpty())
            System.out.println("lista vacia");
        else
            recorreLista(lista);
    }

    /*
     * recorremos lista con videojuegos del mismo nombre
     *
     */
    @Override
    public void consultaNombreProducto(){
        String nombre;
        List<Videojuego> lista = new ArrayList();
        nombre = recogeNombreVideojuego();
        lista=VideojuegoJDBC.consultaVideojuegosNombre(nombre);
        if(lista.isEmpty())
            System.out.println("lista vacia");
        else
            recorreLista(lista);
    }

    /*
     * recorremos lista con videojuegos con el mismo estado
     */
   @Override
    public void consultaEstadoProducto() {
        ProductoEnum[] arrayE = rellenaArrayProductoEnum();
        List<Videojuego> lista = new ArrayList();
        int eligeOpcion;
        ProductoEnum est;
        recorreEstadoProducto();
        eligeOpcion = recogeOpcion(arrayE.length);
        est = arrayE[eligeOpcion];
        lista = VideojuegoJDBC.consultaVideojuegosEstadoProducto(est);
        if(lista.isEmpty())
            System.out.println("lista vacia");
        else
            recorreLista(lista);
    }    
    
    /*
    * recorremos lista con videojeugos del mismo año
    */
    @Override
    public void consultaAñoProducto() throws NullPointerException {
        int anno = 0;
        List<Videojuego> lista = new ArrayList();
        System.out.println("Introduce Año de Videojuego: ");
        anno = introduceDatos.introduceEntero2();
        lista = VideojuegoJDBC.consultaVideojuegosAnno(anno);
        if(lista.isEmpty())
            System.out.println("lista vacia");
        else
            recorreLista(lista);  
    }
    
    /*
     * mostramos videojuego encontrado a partir del codigo que recogemos
     */
    @Override
    public void consultaCodigoProducto()throws NullPointerException {
        int codigo=0;
        codigo = recogeCodigoVideojuego();
        Videojuego video = VideojuegoJDBC.obtenerVideojuegoPorId(codigo);
       try{
            System.out.println(video.toString());
        }catch(NullPointerException e){
            System.out.println("No existe Videojuego");
        }
    }
        
    /*
     * metodo en el que damos de alta un videojuego
     */
    @Override
    public void altaProducto() {
        Videojuego video =recogeDatos();
        VideojuegoJDBC.insertaVideojuego(video);
    }

    /*
     * comprobamos que el genero introducido por el usuario exista
     * 
     * @param gen       es el genero que introduce el usuario por consola
     */
    @Override
    public boolean compruebaGenero(String gen){
        boolean dev=false;
        for (GeneroVideojuegoEnum p : GeneroVideojuegoEnum.values())
        {
            if(p.equals(gen))
            {
                dev=true;
            }
        }
        return dev;
    }
    
    /*
     * metodo que devuelve un listado con las tarifas que se pueden aplicar en el momento 
     * en el que el metodo es invocado.
     * Si no encuentra ninguna, se le aplica una tarifa por defecto al producto.
     */
    @Override
    public List tarifasFiltroTipoProductoFecha(TipoProductoEnum producto){
        List<Tarifa>listaT = TarifaJDBC.listadoTarifasBBDD();
        List<Tarifa> listaFiltroTarifas = new ArrayList();
        int cont=1;
        long fechaActualSistema = System.currentTimeMillis();//guardamos fechaActual de sistema para comparar fechas de tipo long
        long fechaInicioTarifa;
        long fechaFinTarifa;
        String tipoProductoLista;
        String tipoProductoVideojuego = producto.toString();
        System.out.println("---LISTADO DE TARIFAS ACTIVAS ACTUALMENTE---");
        for(Tarifa p: listaT){
            tipoProductoLista=p.getTipoProducto().toString();
            fechaInicioTarifa = p.getFechaInicio().getTime();
            fechaFinTarifa = p.getFechaFin().getTime();
            /* Comparamos que la tarifa que recorremos sea del mismo tipo(para VIDEOJUEGO)
             * Despues comparamos que la fecha actual del sistema esta comprendida dentro de los rangos
             * de fechaInicio y fechaFin de Tarifa para mostrarla (mostramos tarifas activas)
             * De esta forma, conseguimos que muestre solo las tarifas de tipo Videojuego
             * que esten activas en ese momento.
             * 
             * si no hay tarifas activas, se le aplicara una tarifa por defecto.
             */
            if(tipoProductoVideojuego.equalsIgnoreCase(tipoProductoLista) && fechaActualSistema>fechaInicioTarifa && fechaActualSistema<fechaFinTarifa)
            {
                listaFiltroTarifas.add(p);
                System.out.print(cont+".- ");
                System.out.println(p);
                cont++;
            }
        }
        if(listaFiltroTarifas.isEmpty())
            System.out.println("No se encontraron tarifas disponibles");
                return listaFiltroTarifas;
    }

    /*
     * listado de generos de videojuego
     */
    @Override
    public void listadoGenero() {
        int cont=1;
        System.out.println("---GENEROS DE VIDEOJUEGO---");
        for(GeneroVideojuegoEnum p: GeneroVideojuegoEnum.values()){
            System.out.print(cont+".- ");
            System.out.println(p);
            cont++;
        }
    }
    
    /*
     * muestra listado de productos filtrados por proveedor
     */
    @Override
    public void consultaProveedorProducto() {
        int codigo=0;
        codigo = recogeCodigoProveedor();
        List<Videojuego> lista = new ArrayList();
        lista = VideojuegoJDBC.consultaVideojuegosProveedor(codigo);
        if(lista.isEmpty())
            System.out.println("lista vacia");
        else
            recorreLista(lista);
    }
        
    /*
     * muestra listado de productos filtrados por franquicia
     */
    @Override   
    public void consultaFranquiciaProducto() {
        int codigo=0;
        codigo = recogeCodigoFranquicia();
        List<Videojuego> lista = new ArrayList();
        lista = VideojuegoJDBC.consultaVideojuegosFranquicia(codigo);
        if(lista.isEmpty())
            System.out.println("lista vacia");
        else
            recorreLista(lista);
    }    
    
     
    /*
     * rellenamos y devolvemos array de genero. 
     * nos hará falta en otros metodos.
     */
    public GeneroVideojuegoEnum [] rellenaArrayGenero(){
         GeneroVideojuegoEnum [] arrayG = new GeneroVideojuegoEnum[GeneroVideojuegoEnum.values().length];//Guarda enumeracion de generos de videojuegos
         int cont=0;
         for(GeneroVideojuegoEnum g: GeneroVideojuegoEnum.values())
         {
             arrayG[cont]=g;
             cont++;
         }
         return arrayG;
     }
      
    /*
     * metodo donde recogemos datos para dar de alta Videojuego
     */
 
    public Videojuego recogeDatos(){
        GeneroVideojuegoEnum [] arrayG = rellenaArrayGenero();
        ProductoEnum [] arrayE = rellenaArrayProductoEnum();
        List<Tarifa> listaT;
        List<Franquicia> listaFran = FranquiciaJDBC.listadoFranquiciaBBDDAlta();
        List<Proveedor> listaProv = ProveedorJDBC.consultarProveedoresAlta();
        int eligeOpcion;
        boolean dev=false;
        int cod=0,edad,opcionPos,idUbi,anno, numJug;
        ProductoEnum est;
        String titulo, desc, plat;
        double precio;
        Tarifa t;
        Ubicacion ubi=new Ubicacion();
        Proveedor prov;
        Franquicia franq;
        GeneroVideojuegoEnum gen;
        TipoProductoEnum tipo=TipoProductoEnum.Videojuego;

        
        cod=ProductoJDBC.devuelveUltimoId();
        System.out.println("-- ALTA VIDEOJUEGO -- ");
        System.out.println("Introduce Titulo: ");
        titulo=introduceDatos.introduceString2();
        System.out.println("Introduce Descripcion: ");
        desc=introduceDatos.introduceString2();
        System.out.println("Introduce Edad Recomendada: ");
        edad=introduceDatos.introduceEntero2();
        System.out.println("Introduce Precio de Compra: ");
        precio=introduceDatos.introduceDouble2();

        
        recorreEstadoProducto();
        eligeOpcion = recogeOpcion(arrayE.length);
        est=arrayE[eligeOpcion];
        System.out.println(est);


        //recoge la tarifa elegida. Solo se eligiran las tarifa del tipo Videojuego
        //y que esten activas en ese momento(segun fecha del sistema)
        listaT = tarifasFiltroTipoProductoFecha(TipoProductoEnum.Videojuego);
        if(listaT.isEmpty())
        {
            System.out.println("No se encontraron tarifas, se aplicara una por defecto");
            t=TarifaJDBC.DevuelveTarifaPorDefecto(tipo);
        }          
        else
        {
            //recorreListaTarifa(listaT);
            eligeOpcion = recogeOpcion(listaT.size());
            t= listaT.get(eligeOpcion);//guarda tarifa elegida en pelicula
        }
        
        //recoge genero de pelicula elegido
        listadoGenero();
        eligeOpcion = recogeOpcion(arrayG.length);
        gen = arrayG[eligeOpcion];

        //recoge la franquicia elegida
        //recorreListaFranquicia(listaFran);
        //eligeOpcion = recogeOpcion(listaFran.size());
        Franquicia franquicia = FranquiciaJDBC.obtenerFranquiciaPorId(listaFran.get(0).getId()); 
        System.out.println(franquicia.toString());
        //guardamos la primera franquicia que aparezca en la BBDD
        franq = listaFran.get(0);


        //recoge el proveedor elegido
        recorreListaProveedor(listaProv);
        eligeOpcion = recogeOpcion(listaProv.size());
        prov  = listaProv.get(eligeOpcion);

        //recogemos resto de atributos
        System.out.println("Introduce Año: ");
        anno =introduceDatos.introduceEntero2();
        
        System.out.println("Introduce Numero de Jugadores: ");
        numJug= introduceDatos.introduceEntero2();
        
        System.out.println("Introduce Plataforma:");
        plat = introduceDatos.introduceString2();

        //recogemos ubicacion
        ubi=recogeUbicacion();
 
        return new Videojuego(cod, titulo, tipo, est, desc, edad, precio, t, ubi, prov, franq, plat, numJug, gen, anno); 
    }
    
    public String recogeNombreVideojuego(){
        System.out.println("Introduce Nombre de Videojuego: ");
        return introduceDatos.introduceString2();
        
    }
    
    public int recogeCodigoVideojuego(){
        System.out.println("Introduce Codigo de Videojuego: ");
        return introduceDatos.introduceEntero2();
    }   
    
    /*
     * menu de busqueda de videojuego
     */
    public static void menuBuscaVideojuego(){
        int op=0;
        String recoge;
        boolean listo = false;
        Videojuego video = new Videojuego();
        do{           
            do{
                System.out.println("--BUSQUEDA VIDEOJUEGO--");
                System.out.println("[1] Por codigo");
                System.out.println("[2] Por Año");
                System.out.println("[3] Por Titulo");
                System.out.println("[4] Por Proveedor");
                System.out.println("[5] Por Franquicia");
                System.out.println("[6] Por Estado del Producto");
                System.out.println("[7] Por Genero");
                System.out.print(">>> Seleccione una opción: ");
                op = introduceDatos.introduceEntero2();
            }while(op>7 || op<1);
            switch(op)
            {
                case 1:video.consultaCodigoProducto();break;
                case 2:video.consultaAñoProducto();break;
                case 3:video.consultaNombreProducto();break;
                case 4:video.consultaProveedorProducto();break;
                case 5:video.consultaFranquiciaProducto();break;
                case 6:video.consultaEstadoProducto();break;
                case 7:video.consultaGeneroProducto();break;

            }
           System.out.println("\nDesear seguir consultando alguna propiedad del prodcucto actual(s/n): ");
            recoge = introduceDatos.introduceString2();
            do {
                if (recoge.compareToIgnoreCase("s") == 0 || recoge.compareToIgnoreCase("n") == 0) {
                    listo = true;
                } else {
                    System.out.println("Introduzca s/n por favor: ");
                    recoge = introduceDatos.introduceString2();
                }
            } while (!listo);
        } while (recoge.compareToIgnoreCase("s") == 0);
    }



}
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

